import { ArgumentMetadata, Injectable, PipeTransform, HttpException, HttpStatus, Logger, BadRequestException } from '@nestjs/common';
import { plainToClass } from 'class-transformer';
import { validate } from 'class-validator';

@Injectable()
export class ValidationPipe implements PipeTransform<any>{
  async transform(value: any, {metatype}: ArgumentMetadata) {
    console.log('进入全局管道。。。');
    if (!value) {
      throw new BadRequestException(HttpStatus.BAD_REQUEST,'No data submitted');
    }
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToClass(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {//统一抛出异常
      throw new HttpException(this.buildError(errors), HttpStatus.BAD_REQUEST);
    }
    return value;
  }
  private buildError(errors: any[]) {
    const result: any = {};
    errors.forEach(el => {
      const prop = el.property;
      Object.entries(el.constraints).forEach(constraint => {
        result[prop + constraint[0]] = `${constraint[1]}`;
      });
    });
    Logger.error('ValidationPipe', JSON.stringify(result), 'HttpException');
    return result;
  }

  private toValidate(metatype: any): boolean {
    const types = [String, Boolean, Number, Array, Object];
    return !types.find((type) => metatype === type);
  }
}
